﻿using MediatR;
using Microsoft.EntityFrameworkCore;
using T.Materials.API.Application.Command.MaterialRequisitionCommand;
using T.Materials.Repository;
using T.Materials.Repository.MaterialsImpl;
using T.Materials.Repository.MaterialsInterface;

namespace T.Materials.API.Application.CommandHandler.MaterialRequisitionCommandHandler
{
    /// <summary>
    /// 处理删除物料需求命令
    /// </summary>
    public class DeletedMaterialRequisitionCommandHandler : IRequestHandler<DeletedMaterialRequisitionCommand, int>
    {
        /// <summary>
        /// 物资领用仓储接口
        /// </summary>
        protected readonly IMaterialRequisitionRepository materialRequisitionRepository;

        /// <summary>
        /// 上下文
        /// </summary>
        protected readonly MEFDbContext mEFDbContext;

        /// <summary>
        /// 物资仓库接口
        /// </summary>
        protected readonly IMaterialStoreRepository materialStoreRepository;

        /// <summary>
        /// 存储物资领用存储仓储接口
        /// </summary>
        protected readonly IStorageMaterialsRepository storageMaterialsRepository;

        /// <summary>
        /// 映射器
        /// </summary>
        //protected readonly IMapper mapper;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="storageMaterialsRepository">存储物资领用存储仓储接口</param>
        /// <param name="materialRequisitionRepository">物资领用仓储接口</param>
        /// <param name="mEFDbContext">上下文</param>
        /// <param name="materialStoreRepository">物资仓库接口</param>
        /// <param name="mapper">映射器</param>
        public DeletedMaterialRequisitionCommandHandler(IMaterialRequisitionRepository materialRequisitionRepository, MEFDbContext mEFDbContext, IMaterialStoreRepository materialStoreRepository, IStorageMaterialsRepository storageMaterialsRepository)
        {
            this.materialRequisitionRepository = materialRequisitionRepository;
            this.mEFDbContext = mEFDbContext;
            this.materialStoreRepository = materialStoreRepository;
            //this.mapper = mapper;
            this.storageMaterialsRepository = storageMaterialsRepository;
        }

        /// <summary>
        /// 处理删除物料需求命令
        /// </summary>
        /// <param name="request">删除物料需求命令</param>
        /// <param name="cancellationToken">取消标记</param>
        /// <returns>返回受影响的行数</returns>
        public async Task<int> Handle(DeletedMaterialRequisitionCommand request, CancellationToken cancellationToken)
        {
            var strategy = mEFDbContext.Database.CreateExecutionStrategy();
            return await strategy.ExecuteAsync(async () =>
            {
                using (var transaction = mEFDbContext.Database.BeginTransaction())
                {
                    try
                    {
                        //删除物资领用申请
                        var res = await materialRequisitionRepository.GetModelAsync(request.MaterialRequisitionId);
                        res.IsDeleted = true;
                        res.DeletedBy = request.DeletedBy;
                        res.DeletedDate = DateTime.Now;
                        var storageMaterials = await storageMaterialsRepository.GetAsync(x => x.MaterialRequisitionId == res.MaterialRequisitionId);
                        //删除领用详情表信息
                        foreach (var itemTwo in storageMaterials)
                        {
                            itemTwo.IsDeleted = true;
                            itemTwo.DeletedBy = request.DeletedBy;
                            itemTwo.DeletedDate = DateTime.Now;
                            await storageMaterialsRepository.UpdateAsync(itemTwo);
                            //回填物资库存
                            var store = await materialStoreRepository.GetModelAsync(itemTwo.MaterialStoreId);
                            store.Number += itemTwo.QuantityReceived;
                            await materialStoreRepository.UpdateAsync(store);
                        }
                        await materialRequisitionRepository.UpdateAsync(res);
                        // 事务提交
                        transaction.Commit();
                        return 1;
                    }
                    catch (Exception)
                    {
                        // 回滚事务
                        transaction.Rollback();

                        throw;
                    }
                }
            });
        }
    }
}
